package com.wson.adapter.clouddisk.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.kuaipan.client.KuaipanAPI;
import com.kuaipan.client.model.AccessToken;
import com.kuaipan.client.model.KuaipanFile;
import com.kuaipan.client.model.KuaipanPublicLink;
import com.kuaipan.client.model.KuaipanUser;
import com.kuaipan.client.session.OauthSession;
import com.kuaipan.client.session.Session;
import com.kuaipan.test.AuthorizedAPIFactory;
import com.kuaipan.test.KPTestUtility;
import com.wson.adapter.codisk.AbstractCodiskAdapter;
import com.wson.adapter.codisk.ICodiskAdapter;
import com.wson.model.adapter.oauthaccount.IOAuthAccountView;
import com.wson.model.clouddisk.account.ICodiskAccountMeta;
import com.wson.model.clouddisk.account.ICodiskAccountView;
import com.wson.model.clouddisk.file.ICodiskFileManip;
import com.wson.model.clouddisk.file.ICodiskFileMeta;
import com.wson.model.clouddisk.file.ICodiskFileView;
import com.wson.model.clouddisk.file.impl.CodiskFileModel;
import com.wson.model.clouddisk.provider.ICodiskProviderView;
import com.wson.platform.factory.impl.BeanFactory;

public class CodiskAdapterKuaipanImpl extends AbstractCodiskAdapter implements ICodiskAdapter{
	
	//public final static String APP_KEY = "xcBXMk8uVK9DCr30";
	//public final static String APP_SECRET = "PTTmJSuXFUAGYtmp";
	
	public final static int BUFFER_SIZE = 4048;
	public final static String API_HOST = "openapi.kuaipan.cn";
	public final static String CONTENT_HOST = "api-content.dfs.kuaipan.cn";
	public final static String CONV_HOST = "conv.kuaipan.cn";
	
	public final static String AUTH_URL = "https://www.kuaipan.cn/api.php?ac=open&op=authorise&oauth_token=";
	public final static String UPLOAD_LOCATE_URL = "http://api-content.dfs.kuaipan.cn/1/fileops/upload_locate";
	
	
	private Session session;
	private static KuaipanAPI api = null;
	
	public CodiskAdapterKuaipanImpl(ICodiskAccountView account, ICodiskProviderView provider) {
		super(account, provider);
	}


	protected KuaipanAPI  getAPI(){
		//KuaipanAPI api = AuthorizedAPIFactory.getInstance(APP_KEY, APP_SECRET, "00e8164e5420ee4ebc241cd8", "bb10797e744e473f835ae3f080edf6b8");
		if(api==null){
			if(this.getOAuthAccount()!=null){
				ICodiskAccountView account = (ICodiskAccountView)this.getOAuthAccount();
				api = AuthorizedAPIFactory.getInstance(
						this.getOAuthProvider().getAppKey(), 
						this.getOAuthProvider().getAppSecret(), 
						account.getOauthToken(), 
						account.getOauthSecret());
			}
		}
		return api;
	}


	@Override
	protected String generateAuthorizationURL(String callback) throws Exception {
		session = new OauthSession(this.getOAuthProvider().getAppKey(), 
				this.getOAuthProvider().getAppSecret()
				, OauthSession.Root.APP_FOLDER);
		api = new KuaipanAPI(session);
		
		String authorurl = api.requestToken(callback);
		
		return authorurl;
	}

	@Override
	protected void retrieveAccess(IOAuthAccountView account,
			String certification_callback_action, Map<String, Object> params)
			throws Exception {
		AccessToken at = api.accessToken();	
		
		KuaipanUser user = api.accountInfo();
		
		this.saveAssessToken(account, at.key, at.secret, null, ""+user.user_id, user.user_name, user.user_name);

	}






	@Override
	public IOAuthAccountView generateAccessAccount(String certification_callback_action, Map<String, Object> params)
		throws Exception {
		ICodiskAccountView account = (ICodiskAccountView)BeanFactory.getCurrentFactory().getModelFactory().getModel(ICodiskAccountMeta.META_ID);
		this.getOAuthProvider().initModel((ICodiskAccountView)account);
		
		return this.generateAccessAccount(account, certification_callback_action, params);
	}
	

	

	@Override
	public void copydir(String directorysrc, String directorydest)
			throws Exception {
		KuaipanAPI api = this.getAPI();
		api.copy(directorysrc, directorydest);
	}


	@Override
	public void movedir(String directorysrc, String directorydest)
			throws Exception {
		KuaipanAPI api = this.getAPI();
		api.move(directorysrc, directorydest);
	}


	@Override
	public ICodiskFileView mkdir(String path) throws Exception {
		KuaipanAPI api = this.getAPI();//AuthorizedAPIFactory.getInstance(APP_KEY, APP_SECRET, "00e8164e5420ee4ebc241cd8", "bb10797e744e473f835ae3f080edf6b8");
		KuaipanFile dir = api.createFolder("/"+path);
				
		ICodiskFileView result = null;
		try{
			result = (ICodiskFileView)BeanFactory.getCurrentFactory().getModelFactory().getModel(ICodiskFileMeta.META_ID);
		}
		catch(Exception ex){
			result = new CodiskFileModel();
		}
		((ICodiskFileManip)result).setDirectory(true);
		((ICodiskFileManip)result).setPath(dir.path!=null?dir.path:path);
		((ICodiskFileManip)result).setName(dir.name);
		((ICodiskFileManip)result).setCode(dir.file_id);
		((ICodiskFileManip)result).setCreateDate(dir.create_time);
		((ICodiskFileManip)result).setModifyDate(dir.modify_time);
		
		return result;
	}
	
	
	@Override
	public ICodiskFileView upload(ICodiskFileView file) throws Exception {
		return upload(file.getPath(), new ByteArrayInputStream(file.getLongText().getBytes()), file.getLongText().length());
	}


	@Override
	public ICodiskFileView upload(String path, InputStream is, long size)
			throws Exception {
		KuaipanAPI api = this.getAPI();
		
		KuaipanFile file = api.uploadFile(path, is, size, true, null);
		
		ICodiskFileView result = null;
		try{
			result = (ICodiskFileView)BeanFactory.getCurrentFactory().getModelFactory().getModel(ICodiskFileMeta.META_ID);
		}
		catch(Exception ex){
			result = new CodiskFileModel();
		}
		((ICodiskFileManip)result).setName(file.name);
		((ICodiskFileManip)result).setPath(file.path!=null?file.path:path);
		((ICodiskFileManip)result).setCode(file.file_id);
		((ICodiskFileManip)result).setCreateDate(file.create_time);
		((ICodiskFileManip)result).setModifyDate(file.modify_time);
		
		return result;
	}
	
	
	
	@Override
	public String retrieveProvisionUrl(ICodiskFileView dir) throws Exception {
		return "http://www.kuaipan.cn/home.htm?m=kp#kp|"+dir.getCode()+"|0";
	}


	@Override
	public ICodiskFileView uploadshare(String path, InputStream is, long size)
			throws Exception {
		KuaipanAPI api = this.getAPI();
		
		KuaipanFile file = api.uploadFile(path, is, size, true, null);
		
		KuaipanPublicLink link = api.shares(path, null, null);
		
		ICodiskFileView result = null;
		try{
			result = (ICodiskFileView)BeanFactory.getCurrentFactory().getModelFactory().getModel(ICodiskFileMeta.META_ID);
		}
		catch(Exception ex){
			result = new CodiskFileModel();
		}
		((ICodiskFileManip)result).setName(file.name);
		((ICodiskFileManip)result).setPath(file.path!=null?file.path:path);
		((ICodiskFileManip)result).setShareHref(link.url);
		((ICodiskFileManip)result).setCode(file.file_id);
		((ICodiskFileManip)result).setCreateDate(file.create_time);
		((ICodiskFileManip)result).setModifyDate(file.modify_time);
		
		return result;
	}


	@Override
	public String share(String path) throws Exception {
		KuaipanAPI api = this.getAPI();
		KuaipanPublicLink link = api.shares(path, null, null);
		return link.url;
	}
	@Override
	public ICodiskFileView filemeta(String path) throws Exception {
		KuaipanAPI api = this.getAPI();
		KuaipanFile file = api.metadata(path, false);
		
		ICodiskFileView result = null;
		try{
			result = (ICodiskFileView)BeanFactory.getCurrentFactory().getModelFactory().getModel(ICodiskFileMeta.META_ID);
		}
		catch(Exception ex){
			result = new CodiskFileModel();
		}
		((ICodiskFileManip)result).setName(file.name);
		((ICodiskFileManip)result).setPath(file.path!=null?file.path:path);
		((ICodiskFileManip)result).setCode(file.file_id);
		((ICodiskFileManip)result).setCreateDate(file.create_time);
		((ICodiskFileManip)result).setModifyDate(file.modify_time);		
		
		return result;
	}
/*	@Override
	public ICodiskDirectoryView dirmeta(String path) throws Exception {
		KuaipanAPI api = this.getAPI();
		KuaipanFile dir = api.metadata(path, true);
		
		CodiskDirectoryModel result = new CodiskDirectoryModel();//(DirectoryModel)BeanFactory.getCurrentFactory().getModelFactory().getModel(IDirectoryMeta.META_ID);
		result.setPath(dir.path!=null?dir.path:path);
		result.setName(dir.name);
		result.setCode(dir.file_id);
		result.setCreateDate(dir.create_time);
		result.setModifyDate(dir.modify_time);
		
		return result;
	}
	*/
	
	
	@Override
	public List<ICodiskFileView> listfiles(String directory)
			throws Exception {
		KuaipanAPI api = this.getAPI();
		KuaipanFile dir = api.metadata(directory, true);
		List<ICodiskFileView> files = new ArrayList<ICodiskFileView>();
		if(dir!=null && dir.files!=null){
			for(KuaipanFile file : dir.files){
				ICodiskFileView result = (ICodiskFileView)BeanFactory.getCurrentFactory().getModelFactory().getModel(ICodiskFileMeta.META_ID);
				
				((ICodiskFileManip)result).setName(file.name);
				((ICodiskFileManip)result).setPath(file.path!=null?file.path:null);
				((ICodiskFileManip)result).setCode(file.file_id);
				((ICodiskFileManip)result).setCreateDate(file.create_time);
				((ICodiskFileManip)result).setModifyDate(file.modify_time);	
				files.add(result);
			}
		}
		return files;
	}


	@Override
	public ICodiskFileView download(String path) throws Exception {
		KuaipanAPI api = this.getAPI();
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		api.downloadFile(path, os, null);
		String download_content = KPTestUtility.outputStream2String(os);
		
		ICodiskFileView result = null;
		try{
			result = (ICodiskFileView)BeanFactory.getCurrentFactory().getModelFactory().getModel(ICodiskFileMeta.META_ID);
		}
		catch(Exception ex){
			result = new CodiskFileModel();
		}
		((ICodiskFileManip)result).setLongText(download_content);
		
		return result;
	}
	@Override
	public void deletefile(String path) throws Exception {
		KuaipanAPI api = this.getAPI();
		api.delete(path);
		
	}
	@Override
	public void deletedir(String path) throws Exception {
		KuaipanAPI api = this.getAPI();
		api.delete(path);
	}	

	
	
	
}
